<template>
  <div class="container">
    <el-row :gutter="20">
      <el-col :span="8">
        <div class="area-container left-area">
          <div class="title-section">
            <h2 class="section-title">数字人形象选择</h2>
          </div>
          <div class="digital-human-section">
            <!-- Banner 轮播效果 -->
            <el-carousel
                height="220px"
                :autoplay="false"
                indicator-position="none"
                arrow="always"
                @change="handleCarouselChange"
            >
              <el-carousel-item
                  v-for="(item, index) in digitalHumanList.filter(item => item.status === 3)"
                  :key="item.id"
              >
                <div class="banner-item" :class="{ active: index === currentIndex }">
                  <div class="pro-tag" v-if="item.isPro === '1'">Pro</div>
                  <img :src="item.url_image" :alt="item.name" />
                  <div class="banner-name">{{ item.name }}</div>
                </div>
              </el-carousel-item>
            </el-carousel>
            <div class="drive-section">
              <div class="button-group">
                <el-button
                    :type="driveType === 'text' ? 'primary' : 'default'"
                    @click="onDriveTypeChange('text')"
                >
                  文本驱动
                </el-button>
                <el-button
                    :type="driveType === 'audio' ? 'primary' : 'default'"
                    @click="onDriveTypeChange('audio')"
                >
                  音频驱动
                </el-button>
              </div>
              <!-- 文本驱动内容 -->
              <div v-if="driveType === 'text'" class="text-area-container">
                <el-input
                    v-model="formData.textContent"
                    type="textarea"
                    :rows="6"
                    placeholder="请输入文案进行仿写"
                    class="text-area"
                />
              </div>
              <!-- 音频驱动内容 -->
              <div v-if="driveType === 'audio'" class="audio-section">
                <el-button type="primary" class="upload-btn" @click="handleUploadAudio">
                  <el-icon><Upload /></el-icon>
                  上传音频
                </el-button>
                <div class="audio-list">
                  <div v-for="(audio, index) in audioList" :key="index" class="audio-item">
                    <div class="audio-info">
                      <el-icon><Document /></el-icon>
                      <span class="audio-name">{{ audio.name }}</span>
                    </div>
                    <div class="audio-actions">
                      <el-icon class="action-icon" @click="handleDeleteAudio(index)"><Delete /></el-icon>
                    </div>
                  </div>
                </div>
              </div>
              <div v-if="driveType === 'text'" class="generate-count-row">
                <span class="generate-count-label">仿写数量</span>
                <el-input-number v-model="generateCount" :min="1" size="large" class="beauty-counter" />
              </div>
              <div class="switch-row">
                <span class="switch-label">是否包装</span>
                <el-switch
                    v-model="formData.isPackaged"
                    class="custom-switch"
                    @change="handlePackagedChange"
                />
              </div>
              <div class="generate-section">
                <el-button type="primary" class="generate-btn" @click="handleGenerate" v-if="driveType === 'text'">
                  生成
                </el-button>
                <el-button type="default" class="reset-btn" @click="handleReset" style="margin-left: 10px;">
                  重置
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </el-col>
      <el-col :span="16">
        <div class="area-container right-area">
          <el-container direction="vertical" style="height: 100%;">
            <!-- 上区域：标题 -->
            <el-header height="auto" class="title-row" style="flex-shrink: 0;">
              <div class="menu-title">内容为AI生成，你可以自定义修改或增减，您对该内容的使用应严格遵循国家相关法律法规的规定</div>
              <div class="nav-right">
                <button class="nav-btn" @click="handleVideoLibrary">
                  <el-icon class="btn-icon"><VideoCamera /></el-icon>
                  视频库
                </button>
              </div>
            </el-header>
            <el-main class="wechat-list-main" style="padding: 0; flex: 1 1 0; overflow-y: auto;">
              <!-- 输入框区域（仅在未生成视频时显示） -->
              <div v-if="pictureContents.length === 0">
                <div v-for="(item, idx) in streamContent" :key="idx" style="margin-bottom: 16px;">
                  <el-input
                      type="textarea"
                      :rows="4"
                      v-model="streamContent[idx]"
                      placeholder="内容"
                      style="width: 100%;"
                  />
                  <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 4px;">
                    <el-button type="text" style="color: #f56c6c;" @click="handleDeleteContent(idx)">删除</el-button>
                    <div style="display: flex; gap: 8px;">
                      <el-button
                          v-if="audioUrls[idx]"
                          type="text"
                          style="color: #67C23A;"
                      >
                        试听
                      </el-button>
                      <el-button
                          v-if="audioUrls[idx]"
                          type="text"
                          style="color: #409EFF; margin-left: 8px;"
                          @click="handlePlayAudio(idx)"
                      >
                        <el-icon v-if="!audioPlayingStates[idx]">
                          <VideoPlay />
                        </el-icon>
                        <el-icon v-else>
                          <VideoPause />
                        </el-icon>
                      </el-button>
                      <el-button type="text" style="color: #409EFF;" @click="handleConvertToAudio(idx)">转音频</el-button>
                    </div>
                  </div>
                </div>
              </div>
              <!-- 图片框区域（仅在生成视频后显示） -->
              <el-row v-if="pictureContents.length > 0" :gutter="16" style="margin-top: 24px;">
                <el-col v-for="(item, idx) in pictureContents" :key="item.id || idx" :span="8" style="margin-bottom: 16px;">
                  <DouyinShow :item="item" />
                </el-col>
              </el-row>
              <!-- 音频框区域：仅音频驱动时显示 -->
              <div v-if="driveType === 'audio' && audioList.length > 0" class="audio-list-area">
                <div v-for="(audio, idx) in audioList" :key="audio.url" class="audio-list-item">
                  <template v-if="audio.cover">
                    <img :src="audio.cover" alt="cover" class="audio-cover" />
                  </template>
                  <div class="audio-info-block">
                    <div class="audio-name">{{ audio.name }}</div>
                    <audio :src="audio.url" controls class="audio-player"></audio>
                  </div>
                </div>
              </div>
            </el-main>
            <el-footer height="auto" class="generate-video-bottom" style="flex-shrink: 0;">
              <template v-if="pictureContents.length === 0 && streamContent.length > 0">
                <span style="font-size: 16px; color: #fff; margin-right: 18px;">生成{{ streamContent.length }}条视频</span>
                <el-button type="primary" style="font-size: 15px;" @click="handleGenerateVideo">
                  <el-icon style="vertical-align: middle; margin-right: 4px;"><i class="el-icon-s-promotion" /></el-icon>
                  生成视频
                </el-button>
              </template>
              <template v-if="audioList.length > 0">
                <span style="font-size: 16px; color: #fff; margin-right: 18px;">生成{{ audioList.length }}条视频</span>
                <el-button type="primary" style="font-size: 15px;" @click="handleGenerateVideo">
                  <el-icon style="vertical-align: middle; margin-right: 4px;"><i class="el-icon-s-promotion" /></el-icon>
                  生成视频
                </el-button>
              </template>
              <template v-if="pictureContents.length > 0">
                <el-button type="primary" style="font-size: 15px;" @click="handlePublicVideo">
                  授权发布
                </el-button>
              </template>
            </el-footer>
          </el-container>
        </div>
      </el-col>
    </el-row>
  </div>

  <!-- 任务名称输入弹出框 -->
  <el-dialog
    v-model="dialogVisible"
    title="请输入任务名称"
    width="400px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-input
      v-model="taskName"
      placeholder="请输入任务名称"
      clearable
      @keyup.enter="confirmTaskName"
    />
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmTaskName">确认</el-button>
      </span>
    </template>
  </el-dialog>

  <MyDialog
    v-model="showUploadAudioDialog"
    title="音频上传"
    width="50%"
    :modal="true"
    :close-on-click-modal="false"
    @confirm="handleUploadAudioConfirm"
  >
    <SourceAudioNew ref="sourceAudioNewRef" @confirm="handleUploadAudioConfirm"/>
  </MyDialog>

  <!-- 发布设置弹窗 -->
  <MyDialog
    v-model="showPublishDialog"
    title="发布设置"
    width="600px"
    :modal="true"
    :close-on-click-modal="false"
    @confirm="handlePublishConfirm"
    @cancel="handlePublishCancel"
  >
    <div class="publish-form">
      <!-- 发布类型 -->
      <div class="form-section">
        <div class="section-label">发布类型</div>
        <div class="publish-type-buttons">
          <button
            :class="['type-btn', publishForm.publishType === 'douyin' ? 'active' : '']"
            @click="publishForm.publishType = 'douyin'"
          >
            抖音发布
          </button>
<!--          <button
            :class="['type-btn', publishForm.publishType === 'xiaohongshu' ? 'active' : '']"
            @click="publishForm.publishType = 'xiaohongshu'"
          >
            小红书发布
          </button>-->
        </div>
      </div>

      <!-- 活动名称 -->
      <div class="form-section">
        <div class="section-label">活动名称</div>
        <el-input
          v-model="publishForm.activityName"
          placeholder="请输入活动名称"
          class="form-input"
        />
      </div>

      <!-- 标题 -->
      <div class="form-section">
        <div class="section-label">标题</div>
        <el-input
          v-model="publishForm.title"
          type="textarea"
          :rows="2"
          placeholder="发布时标题会自动携带(数字人请手动录入)"
          class="form-input"
        />

      </div>

      <!-- 话题 -->
      <div class="form-section">
        <div class="section-label">话题</div>
        <el-input-tag
          v-model="publishForm.topic"
          placeholder="请输入话题，按回车添加"
          class="form-input"
        />
        <div class="form-tip">
          <el-icon><InfoFilled /></el-icon>
          一行代表一个话题
        </div>
      </div>

      <!-- 挂载 -->
      <div class="form-section" v-if="publishForm.publishType === 'douyin'">
        <div class="section-label">挂载</div>
        <div class="mount-buttons">
          <button
            :class="['mount-btn', publishForm.mount === 'none' ? 'active' : '']"
            @click="publishForm.mount = 'none'"
          >
            无
          </button>
          <button
            :class="['mount-btn', publishForm.mount === 'poi' ? 'active' : '']"
            @click="publishForm.mount = 'poi'"
          >
            POI地址/团购
          </button>
          <button
            :class="['mount-btn', publishForm.mount === 'miniprogram' ? 'active' : '']"
            @click="publishForm.mount = 'miniprogram'"
          >
            小程序
          </button>
        </div>
      </div>
      <!-- POI -->
      <div class="form-section" v-if="publishForm.publishType === 'douyin' && publishForm.mount === 'poi'">
        <div class="section-label">挂载内容</div>
        <div style="display: flex; gap: 8px; width: 100%;">
          <el-input v-model="publishForm.poi1" placeholder="请输入关键词" style="flex:1;" />
          <el-input v-model="publishForm.poi2" placeholder="请输入城市" style="flex:1;" />
          <el-button icon="el-icon-search" type="primary" @click="handleChooseCityKeyWord">搜索</el-button>
        </div>
        <div style="margin-top: 8px;">
          <el-select v-model="publishForm.poiSelect" placeholder="请选择" style="width: 100%;">
            <el-option v-for="item in cityData" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </div>
      </div>
      <!-- 小程序 -->
      <div class="form-section" v-if="publishForm.publishType === 'douyin' && publishForm.mount === 'miniprogram'">
        <div class="section-label">挂载内容</div>
        <el-input v-model="publishForm.miniId" placeholder="例如：ttef91b112671b152ba ID" style="margin-bottom: 8px;" />
        <el-input v-model="publishForm.miniTitle" placeholder="请输入小程序标题" style="margin-bottom: 8px;" />
        <el-input v-model="publishForm.miniPath" placeholder="例如：path/pages/index" />
      </div>
      <!-- 数据获取 -->
      <!-- <div class="form-section" v-if="publishForm.publishType === 'douyin'">
        <div class="section-label">数据获取</div>
        <div class="data-acquisition-row">
          <el-switch
            v-model="publishForm.dataAcquisition"
            active-color="#409EFF"
          />
          <div class="form-tip">
            <el-icon><InfoFilled /></el-icon>
            打开数据获取后,需要用户确定授权
          </div>
        </div>
      </div> -->

      <!-- 随机图片数量 -->
      <div class="form-section">
        <div class="section-label">随机图片数量</div>
        <el-input-number
          v-model="publishForm.picnums"
          :min="0"
          :max="9999"
          class="scan-limit-input"
        />
      </div>

      <!-- 扫码数量限制 -->
      <div class="form-section">
        <div class="section-label">扫码数量限制</div>
        <el-input-number
          v-model="publishForm.scanCodeLimit"
          :min="0"
          :max="9999"
          class="scan-limit-input"
        />
      </div>
    </div>
  </MyDialog>

  <!-- 二维码显示弹窗 -->
  <MyDialog
    v-model="showQrCodeDialog"
    title="请扫码发布"
    width="600px"
    :modal="true"
    :close-on-click-modal="false"
    @confirm="handleQrCodeConfirm"
    @cancel="handleQrCodeConfirm"
  >
    <!-- 二维码显示区域 -->
    <div class="form-section" v-if="douyinQrCode || redBookAndroidQrCode || redBookIOSQrCode">
      <div class="qr-code-container">
        <!-- 抖音二维码 -->
        <div v-if="douyinQrCode" class="qr-code-item">
          <div class="qr-code-title">抖音二维码</div>
          <img :src="douyinQrCode" alt="抖音二维码" class="qr-code-image" />
        </div>
        <!-- 小红书Android二维码 -->
        <div v-if="redBookAndroidQrCode" class="qr-code-item">
          <div class="qr-code-title">小红书Android二维码</div>
          <img :src="redBookAndroidQrCode" alt="小红书Android二维码" class="qr-code-image" />
        </div>
        <!-- 小红书iOS二维码 -->
        <div v-if="redBookIOSQrCode" class="qr-code-item">
          <div class="qr-code-title">小红书iOS二维码</div>
          <img :src="redBookIOSQrCode" alt="小红书iOS二维码" class="qr-code-image" />
        </div>
      </div>
    </div>
  </MyDialog>
</template>

<script setup lang="ts">
import {onMounted, ref, computed} from 'vue'
import axiosUtil from '../../axios-util/axios-util'
import {VideoCamera, Plus, Upload, Document, Delete, InfoFilled, VideoPlay, VideoPause} from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import LocalStorageUtil from "../../utils/LocalStorageUtil.ts";
import { ElLoading,ElMessage } from 'element-plus'
import DouyinShow from '../pages/DouyinShow.vue'
import type { PictureContent } from '../../utils/types'
import MyDialog from '../common/MyDialog.vue'
import SourceAudioNew from '../videoWarehouse/SourceAudioNew.vue'
import utils from '../../utils/utils.ts';
import QRCode from 'qrcode'

//主题控制light  dark
const theme = utils.getTheme();

const router = useRouter()

const formData = ref({
  textContent: '',
  isPackaged: false
})

const generateCount = ref(0)

const streamContent = ref([]);
// 存储音频URL的数组，与streamContent对应
const audioUrls = ref([])

// 存储音频播放状态的数组，与streamContent对应
const audioPlayingStates = ref([])

// 存储音频实例的数组，与streamContent对应
const audioInstances = ref([])

// 图片内容列表
const pictureContents = ref<PictureContent[]>([])

onMounted(() => {
  initPersonVideo()
  initPersonVideoPro()
  // 初始化时清空所有相关变量
  clearAllVariables()
})

// 清空所有变量的函数
const clearAllVariables = () => {
  formData.value = {
    textContent: '',
    isPackaged: false
  }
  generateCount.value = 0
  streamContent.value = []
  audioUrls.value = []
  audioPlayingStates.value = []
  audioInstances.value = []
  pictureContents.value = []
  audioList.value = []
  taskName.value = ''
  currentIndex.value = 0
  driveType.value = 'text'
}

// 手动重置所有变量
const handleReset = () => {
  // 先停止所有正在播放的音频
  audioInstances.value.forEach((instance, index) => {
    if (instance && audioPlayingStates.value[index]) {
      instance.pause();
    }
  });

  clearAllVariables()
  ElMessage.success('已重置所有内容')
}

// 数字人列表数据
const digitalHumanList = ref([])

// 驱动类型
const driveType = ref('text')

// 音频列表
const audioList = ref<{ name: string; url: string; cover: string;mediaId :string;duration :string }[]>([
])

const currentIndex = ref(0)
const handleCarouselChange = (index: number) => {
  currentIndex.value = index
}

const initPersonVideo = async () => {
  const response = await axiosUtil.post('api/digitalpeople/profilelist', {})
  if(response.data.code === 1){
    let data = response.data.data
    data.forEach(item => {
      item.isPro = '2'
    })
    digitalHumanList.value.push(...data)
  }
}

const initPersonVideoPro = async () => {
  const response = await axiosUtil.post('api/digitalpeople/profilelist', {
    "protype": 2
  })
  if(response.data.code === 1){
    let data = response.data.data
    data.forEach(item => {
      item.isPro = '1'
    })
    digitalHumanList.value.push(...data)
  }
}

const prevBanner = () => {
  const len = digitalHumanList.value.length;
  currentIndex.value = (currentIndex.value - 1 + len) % len;
};
const nextBanner = () => {
  const len = digitalHumanList.value.length;
  currentIndex.value = (currentIndex.value + 1) % len;
};
const selectBanner = (idx: number) => {
  if (idx === 0) prevBanner();
  if (idx === 2) nextBanner();
};

const handleSelectDigitalHuman = () => {
  // 先停止所有正在播放的音频
  audioInstances.value.forEach((instance, index) => {
    if (instance && audioPlayingStates.value[index]) {
      instance.pause();
    }
  });

  // 清空生成的内容
  pictureContents.value = [];
  streamContent.value = [];
  audioUrls.value = [];
  audioPlayingStates.value = [];
  audioInstances.value = [];
  taskName.value = '';
  formData.value.textContent = '';
  generateCount.value = 0;
}

const handleVideoLibrary = () => {
  router.push('/videoWarehouse')
}

const showUploadAudioDialog = ref(false)
const sourceAudioNewRef = ref()

// 替换上传音频按钮事件
const handleUploadAudio = () => {
  showUploadAudioDialog.value = true
}

// 确认音频上传弹窗
const handleUploadAudioConfirm = () => {
  if (sourceAudioNewRef.value && sourceAudioNewRef.value.getSelectMateriaAll) {
    const selected = sourceAudioNewRef.value.getSelectMateriaAll()
    if (selected) {
      // 只允许单选，audioList 只保留一个
      audioList.value = [{
        name: selected.title,
        url: selected.url,
        duration: selected.duration,
        mediaId: selected.mediaId,
        cover: selected.cover
      }]
      // 先停止所有正在播放的音频
      audioInstances.value.forEach((instance, index) => {
        if (instance && audioPlayingStates.value[index]) {
          instance.pause();
        }
      });

      // 清空其他相关变量
      streamContent.value = [];
      audioUrls.value = [];
      audioPlayingStates.value = [];
      audioInstances.value = [];
      pictureContents.value = [];
      taskName.value = '';
    }
  }
  showUploadAudioDialog.value = false
}

// 处理删除音频
const handleDeleteAudio = (index: number) => {
  audioList.value.splice(index, 1)
        // 先停止所有正在播放的音频
      audioInstances.value.forEach((instance, index) => {
        if (instance && audioPlayingStates.value[index]) {
          instance.pause();
        }
      });

      // 清空相关变量
      if (audioList.value.length === 0) {
        pictureContents.value = [];
        streamContent.value = [];
        audioUrls.value = [];
        audioPlayingStates.value = [];
        audioInstances.value = [];
        taskName.value = '';
      }
}

// loading 动态文本
const loadingTexts = [
  '文案生成中',
];
// 音频转换 loading 动态文本
const audioLoadingTexts = [
  '音频转换中',
];
let loadingIndex = 0;
let loadingTextTimer: any = null;
let loadingInstance: any = null;
// 音频转换 loading 相关变量
let audioLoadingIndex = 0;
let audioLoadingTextTimer: any = null;
let audioLoadingInstance: any = null;

const handleGenerate = async () => {
  // 开启 loading
  loadingIndex = 0;
  loadingInstance = ElLoading.service({
    lock: true,
    text: loadingTexts[0],
    background: 'rgba(0, 0, 0, 0.7)'
  });
  loadingTextTimer = setInterval(() => {
    loadingIndex = (loadingIndex + 1) % loadingTexts.length;
    if (loadingInstance) loadingInstance.setText(loadingTexts[loadingIndex]);
  }, 1200);

  // 如果已经存在文案，则追加而不是替换
  const existingContent = streamContent.value.length > 0;
  try {
    const url = "https://qianwen1.zhanacun.com/api/aliyun_tongyi/qian_wen/get_index_max?question="
        + encodeURIComponent(formData.value.textContent)
        + "&num=" + generateCount.value
        + "&types=数字人模型&format=标题 跟 内容&original_keywords=原文"
        + "&model=&keywords=&token=" + LocalStorageUtil.get("token")
        + "&storeid=" + LocalStorageUtil.get("id");

    const response = await fetch(url, { method: 'GET' });
    if (!response.body) {
      // 如果无法获取流式数据，只在没有现有内容时设置错误信息
      if (!existingContent) {
        streamContent.value = ['无法获取流式数据'];
      } else {
        streamContent.value.push('无法获取流式数据');
      }
      return;
    }
    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let done = false;
    let lastGptMessage = '';
    let buffer = '';
    while (!done) {
      const { value, done: readerDone } = await reader.read();
      if (value) {
        buffer += decoder.decode(value, { stream: true });
        // 处理多条消息（有可能一次读到多条 event）
        const lines = buffer.split('\n');
        buffer = lines.pop() || ''; // 剩下的部分留给下次
        for (let i = 0; i < lines.length; i++) {
          const line = lines[i];
          if (line.trim().startsWith('event: gpt_message')) {
            // 下一个非空行就是 data
            let j = i + 1;
            while (j < lines.length && lines[j].trim() === '') j++;
            const dataLine = lines[j];
            if (dataLine && dataLine.trim().startsWith('data:')) {
              try {
                const dataStr = dataLine.trim().replace(/^data:\s*/, '');
                const dataObj = JSON.parse(dataStr);
                if (
                    dataObj &&
                    dataObj.data &&
                    dataObj.data.message &&
                    dataObj.data.message.content
                ) {
                  lastGptMessage = dataObj.data.message.content;
                }
              } catch (e) {
                // 忽略解析错误
              }
            }
          }
        }
      }
      done = readerDone;
    }
    // 用\n分割，过滤空行，并去掉前面的数字和点
    const newContent = lastGptMessage
        ? lastGptMessage.split('\n')
            .filter(line => line.trim() !== '')
            .map(line => line.replace(/^\d+\.\s*/, '')) // 去掉开头的数字和点
        : [];

    // 如果已经存在文案，则追加；否则替换
    if (newContent.length > 0) {
      if (existingContent) {
        streamContent.value.push(...newContent);
      } else {
        streamContent.value = newContent;
      }
    } else if (!existingContent) {
      // 只有在没有现有内容且没有获取到新内容时才设置提示
      streamContent.value = ['未获取到有效内容'];
    }

    // 生成成功后不清空输入框，保持用户输入的内容
    // formData.value.textContent = '';
  } catch (e) {
    // 如果出错，只在没有现有内容时设置错误信息
    if (!existingContent) {
      streamContent.value = ['请求出错：' + e];
    } else {
      // 如果已有内容，则追加错误信息
      streamContent.value.push('请求出错：' + e);
    }
  } finally {
    // 关闭 loading
    clearInterval(loadingTextTimer);
    if (loadingInstance) loadingInstance.close();
  }
};

// 删除streamContent中某项
const handleDeleteContent = (idx: number) => {
  // 如果正在播放音频，先停止
  if (audioInstances.value[idx]) {
    audioInstances.value[idx].pause()
    audioInstances.value[idx] = null
  }

  streamContent.value.splice(idx, 1)
  // 同时删除对应的音频URL、播放状态和音频实例
  audioUrls.value.splice(idx, 1)
  audioPlayingStates.value.splice(idx, 1)
  audioInstances.value.splice(idx, 1)
}
// 转音频事件
const handleConvertToAudio = async (idx: number) => {
  // 获取当前banner对象
  const currentBanner = digitalHumanList.value[currentIndex.value];
  if(!currentBanner.voice_id){
    ElMessage.warning("请先选择音色");
    return;
  }

  // 开启音频转换 loading
  audioLoadingIndex = 0;
  audioLoadingInstance = ElLoading.service({
    lock: true,
    text: audioLoadingTexts[0],
    background: 'rgba(0, 0, 0, 0.7)'
  });
  audioLoadingTextTimer = setInterval(() => {
    audioLoadingIndex = (audioLoadingIndex + 1) % audioLoadingTexts.length;
    if (audioLoadingInstance) audioLoadingInstance.setText(audioLoadingTexts[audioLoadingIndex]);
  }, 1200);

  // 关闭loading的辅助函数
  const closeLoading = () => {
    clearInterval(audioLoadingTextTimer);
    if (audioLoadingInstance) {
      audioLoadingInstance.close();
      audioLoadingInstance = null;
    }
  };

  try {
    const response = await axiosUtil.post('api/volcengine/SubmitAudioProduceJob', {
      "text": streamContent.value[idx],
      "voice": currentBanner.voice
    })

    if(response.data.url){
      // 保存音频URL到对应位置
      audioUrls.value[idx] = response.data.url;
      // 初始化播放状态
      audioPlayingStates.value[idx] = false;
      audioInstances.value[idx] = null;
      ElMessage.success("音频生成成功！");
      // 立即关闭loading
      closeLoading();
    } else {
      // 创建定时器，每3秒检查一次任务状态
      let timer: any = null;
      const checkJobStatus = async () => {
        try {
          const responseSon = await axiosUtil.post('api/volcengine/GetSmartHandleJob', {
            "JobId": response.data.jobId
          })
          if(responseSon.data.state === 'Finished'){
            // 任务完成，清除定时器
            if (timer) {
              clearInterval(timer);
              timer = null;
            }
            // 这里可以添加任务完成后的处理逻辑
            const responseGrandSon = await axiosUtil.post('api/aliyun/GetMediaInfo', {
              "MediaId": responseSon.data.jobResult.mediaId
            })
            if(responseGrandSon.data.mediaInfo.mediaBasicInfo.inputURL){
              audioUrls.value[idx] = responseGrandSon.data.mediaInfo.mediaBasicInfo.inputURL
              // 初始化播放状态
              audioPlayingStates.value[idx] = false;
              audioInstances.value[idx] = null;
              ElMessage.success("音频生成成功！");
            }
            // 任务完成后关闭loading
            closeLoading();
          }
        } catch (error) {
          console.error('检查任务状态失败:', error);
          if (timer) {
            clearInterval(timer);
            timer = null;
          }
          ElMessage.error("音频生成失败，请重试");
          // 出错时关闭loading
          closeLoading();
        }
      }

      // 立即执行一次检查
      await checkJobStatus();

      // 设置定时器，每3秒执行一次
      timer = setInterval(checkJobStatus, 3000);
    }
  } catch (error) {
    ElMessage.error("音频生成失败，请重试");
    // 出错时关闭loading
    closeLoading();
  }

  console.log('当前banner对象:', currentBanner);
  // 这里实现转音频的逻辑
  console.log('转音频', streamContent.value[idx])
}

// 试听音频事件
const handlePlayAudio = (idx: number) => {
  const audioUrl = audioUrls.value[idx];
  if (!audioUrl) return;

  // 如果当前索引没有音频实例，创建一个
  if (!audioInstances.value[idx]) {
    audioInstances.value[idx] = new Audio(audioUrl);

    // 监听音频播放结束事件
    audioInstances.value[idx].addEventListener('ended', () => {
      audioPlayingStates.value[idx] = false;
    });

    // 监听音频播放错误事件
    audioInstances.value[idx].addEventListener('error', () => {
      audioPlayingStates.value[idx] = false;
      ElMessage.error("播放音频失败，请重试");
    });
  }

  const audio = audioInstances.value[idx];

  if (audioPlayingStates.value[idx]) {
    // 如果正在播放，则暂停
    audio.pause();
    audioPlayingStates.value[idx] = false;
  } else {
    // 如果暂停或未播放，则播放
    // 先停止其他正在播放的音频
    audioInstances.value.forEach((instance, index) => {
      if (index !== idx && instance && audioPlayingStates.value[index]) {
        instance.pause();
        audioPlayingStates.value[index] = false;
      }
    });

    audio.play().then(() => {
      audioPlayingStates.value[idx] = true;
    }).catch(error => {
      console.error('播放音频失败:', error);
      ElMessage.error("播放音频失败，请重试");
      audioPlayingStates.value[idx] = false;
    });
  }
}

// 任务名称输入框的响应式数据
const taskName = ref('')
const dialogVisible = ref(false)

// 生成视频按钮事件
const handleGenerateVideo = async () => {
  // 先弹出输入框
  dialogVisible.value = true
}

// 确认任务名称后的处理函数
const confirmTaskName = async () => {
  if (!taskName.value.trim()) {
    ElMessage.warning('请输入任务名称')
    return
  }

  dialogVisible.value = false

  // loading 动画文案
  let loadingTexts = [
    '预计十分钟生成',
    '中途退出不影响后续生成使用'
  ];
  let loadingIndex = 0;
  let videoLoadingInstance = ElLoading.service({
    lock: true,
    text: loadingTexts[0],
    background: 'rgba(0, 0, 0, 0.7)'
  });
  let loadingTextTimer = setInterval(() => {
    loadingIndex = (loadingIndex + 1) % loadingTexts.length;
    if (videoLoadingInstance) videoLoadingInstance.setText(loadingTexts[loadingIndex]);
  }, 1200);

  // 这里实现生成视频的逻辑
  let audioData = []
  //获取当前banner对象
  const currentBanner = digitalHumanList.value[currentIndex.value];

  // 创建一个Promise来等待所有音频生成完成
  const waitForAudioGeneration = async () => {
    if(driveType.value === 'text'){
      //文本驱动的话
      if(currentBanner.voice_id){
        if(!streamContent.value){
          ElMessage.warning(`请先输入文案`)
          return
        }
        // 使用 for...of 循环替代 forEach，这样可以正确使用 await
        for (const item of streamContent.value) {
          try {
            const response = await axiosUtil.post('api/volcengine/SubmitAudioProduceJob', {
              "text": item,
              "voice": currentBanner.voice
            })
            // 处理响应数据
            if (response.data.url) {
              audioData.push({
                "url": response.data.url,
                "url_image": "",
                "mediaId": "",
                "height": "",
                "width": "",
                "duration": response.data.duration,
                "type": response.data.type,
                "text": item
              })
            }else {
                             // 使用Promise包装定时器轮询查询任务状态
               const jobId = response.data.jobId;
               await new Promise<void>((resolve, reject) => {
                const pollTimer = setInterval(async () => {
                  try {
                    const responseSon = await axiosUtil.post('api/volcengine/GetSmartHandleJob', {
                      "JobId": jobId
                    })

                    if(responseSon.data.state === 'Finished'){
                      // 任务完成，清除定时器
                      clearInterval(pollTimer);

                      const responseGrandSon = await axiosUtil.post('api/aliyun/GetMediaInfo', {
                        "MediaId": responseSon.data.jobResult.mediaId
                      })
                      if(responseGrandSon.data.mediaInfo.mediaBasicInfo.inputURL){
                        audioData.push({
                          "url": responseGrandSon.data.mediaInfo.mediaBasicInfo.inputURL,
                          "url_image": "",
                          "mediaId": responseGrandSon.data.mediaInfo.mediaBasicInfo.mediaId,
                          "height": 0,
                          "width": 0,
                          "duration": responseGrandSon.data.mediaInfo.fileInfoList[0].fileBasicInfo.duration,
                          "type": responseGrandSon.data.mediaInfo.mediaBasicInfo.mediaType,
                          "text": item
                        })
                      }
                      resolve();
                    }
                    // 如果状态不是Finished，继续轮询（每5秒执行一次）
                  } catch (error) {
                    console.error('轮询任务状态失败:', error);
                    clearInterval(pollTimer);
                    ElMessage.error(`轮询任务状态失败: ${item}`);
                    reject(error);
                  }
                }, 5000); // 每5秒执行一次
              });
            }
          } catch (error) {
            console.error('音频生成失败:', error)
            ElMessage.error(`音频生成失败: ${item}`)
          }
        }
      }else {
        ElMessage.warning(`请先选择包装音色`)
        return
      }
    }else {
      //音频驱动
      if(audioList.value && audioList.value.length > 0){
        for (const item of audioList.value) {
          audioData.push({
            "url": item.url,
            "url_image": "",
            "mediaId": item.mediaId,
            "width": 0, // 宽度（音频一般为0）
            "height": 0, // 高度（音频一般为0）
            "duration": item.duration,
            "type": "audio/mpeg"
          })
        }
      }else {
        ElMessage.warning(`请先上传音频`)
        return
      }
    }
  };

  // 等待音频生成完成
  await waitForAudioGeneration();

  // 等待数字人视频生成完成
  await new Promise<void>((resolve, reject) => {
    const generateDigitalHumanVideo = async () => {
      try {
        const personRes = await axiosUtil.post('api/digitalpeople/adddigitalpeople', {
          "video_url_audio": encodeURIComponent(JSON.stringify(audioData)),
          "title": taskName.value,
          "ossnum": streamContent.value.length,
          "profile_id": currentBanner.id,
          "packing_id": formData.value.isPackaged ? 1 : 0,
          "pc_status": 0,
          "protype": ""
        })
        if(personRes.data.code===1){
          audioList.value = []
          const id = personRes.data.data.id;
          // 轮询查询生成状态
          let timer = setInterval(async () => {
            try {
              const listRes = await axiosUtil.post('api/digitalpeople/list', {
                "id": id,
                "offset": 1,
                "type": 2,
                "status": "",
                "limit": streamContent.value.length,
                "title": taskName.value,
                "ids": "",
                "protype": ""
              })
              if(listRes.data.code===1){
                if (listRes.data.data.data.status !== 1) {
                  const arr = listRes.data.data.rows
                  arr.forEach(picData => {
                    const picShow = {
                      id: picData.id,
                      bg: picData.video_url_image,
                      avatar: 'https://img2.baidu.com/it/u=2328777830,2201725034&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
                      likes: 9999,
                      comments: 9999,
                      favorites: 9999,
                      shares: 9999,
                      author: '@智慧AI测试',
                      desc: picData.text||"",
                      url: picData.video_url
                    }
                    const idx = pictureContents.value.findIndex(item => item.id === picData.id);
                    if (idx !== -1) {
                      pictureContents.value[idx] = picShow;
                    } else {
                      pictureContents.value.push(picShow);
                    }
                  })
                }
                // 生成完成
                if(listRes.data.data.data.status === 3){
                  clearInterval(timer);
                  clearInterval(loadingTextTimer);
                  if (videoLoadingInstance) videoLoadingInstance.close();
                  ElMessage.success('生成视频成功');

                  // 先停止所有正在播放的音频
                  audioInstances.value.forEach((instance, index) => {
                    if (instance && audioPlayingStates.value[index]) {
                      instance.pause();
                    }
                  });

                  // 生成成功后清空相关变量
                  streamContent.value = [];
                  audioUrls.value = [];
                  audioPlayingStates.value = [];
                  audioInstances.value = [];
                  taskName.value = '';
                  formData.value.textContent = '';
                  generateCount.value = 0;

                  // 可在此处处理生成后数据，如刷新列表等
                  resolve();
                }
              } else {
                // 失败也要关闭 loading
                clearInterval(timer);
                clearInterval(loadingTextTimer);
                if (videoLoadingInstance) videoLoadingInstance.close();
                ElMessage.error('生成视频出错');
                reject(new Error('生成视频出错'));
              }
            } catch (e) {
              clearInterval(timer);
              clearInterval(loadingTextTimer);
              if (videoLoadingInstance) videoLoadingInstance.close();
              ElMessage.error('生成视频出错');
              reject(e);
            }
          }, 3000);
        } else {
          clearInterval(loadingTextTimer);
          if (videoLoadingInstance) videoLoadingInstance.close();
          ElMessage.error("生成失败，请重试");
          reject(new Error("生成失败，请重试"));
        }
      } catch (e) {
        clearInterval(loadingTextTimer);
        if (videoLoadingInstance) videoLoadingInstance.close();
        ElMessage.error("生成失败，请重试");
        reject(e);
      }
    };

    generateDigitalHumanVideo();
  });

  // 所有操作完成后的代码
  console.log('所有音频生成和数字人视频生成都已完成');
  // 在这里可以添加871行之后需要执行的代码
}

// 发布设置弹窗相关
const showPublishDialog = ref(false)
const publishForm = ref({
  publishType: 'douyin', // douyin 或 xiaohongshu
  activityName: '',
  title: '',
  topic: [], // Changed to array for InputTag
  mount: 'none', // none, poi, miniprogram
  dataAcquisition: false,
  scanCodeLimit: 0,
  picnums: 0,
  // POI相关字段
  poi1: '',
  poi2: '',
  poiSelect: '',
  // 小程序相关字段
  miniId: '',
  miniTitle: '',
  miniPath: ''
})

const cityData = ref([])

// 二维码相关
const showQrCodeDialog = ref(false)
const douyinQrCode = ref("")
const redBookAndroidQrCode = ref("")
const redBookIOSQrCode = ref("")

// 生成二维码的函数
const generateQRCode = async (text: string): Promise<string> => {
  try {
    const qrCodeDataUrl = await QRCode.toDataURL(text, {
      width: 200,
      margin: 2,
      color: {
        dark: '#000000',
        light: '#FFFFFF'
      }
    })
    return qrCodeDataUrl
  } catch (error) {
    console.error('生成二维码失败:', error)
    return ''
  }
}

// 发布设置弹窗处理方法
const handlePublishConfirm = async () => {
  console.log('发布设置确认', publishForm.value)
  let videos = ''
  let arr = []
  if(pictureContents.value.length > 0) {
    pictureContents.value.forEach(video => {
      arr.push(video.url)
    })
  }else {
    ElMessage.warning('请先生成视频')
    return
  }
  videos = arr.join(",")

  // TODO: 在这里处理发布逻辑
  let url = ''
  let data: any = {
    "title": publishForm.value.activityName,
    "video_text": publishForm.value.title,
    "video_text_keyword": publishForm.value.topic,
    "platform_type": "none",
    "micro_app_info": {
      "micro_app_id": "",
      "micro_app_title": "",
      "micro_app_url": ""
    },
    "open_data": publishForm.value.dataAcquisition?1:0,
    "video_list": videos,
    "max_release_num": publishForm.value.scanCodeLimit,
    "type": "video",
    "photos": "",
    "photos_num": publishForm.value.picnums,
    "id": ""
  }

  if(publishForm.value.publishType === 'douyin'){
    url = 'api/scan_publish/douyin/save';
    // 处理POI挂载
    if(publishForm.value.mount === 'poi'){
      if(!publishForm.value.poiSelect){
        ElMessage.warning("请先选择数据")
        return
      }else {
        const selectArr = cityData.value.find(item => item.value === publishForm.value.poiSelect)
        if(selectArr){
          data.mount_type = 'poi'
          data.poi_id = selectArr.value
          data.poi_name = selectArr.label
        }
      }
    }

    // 处理小程序挂载
    if(publishForm.value.mount === 'miniprogram'){
      if(!publishForm.value.miniId){
        ElMessage.warning("请先输入小程序ID")
        return
      }
      if(!publishForm.value.miniTitle){
        ElMessage.warning("请先输入标题")
        return
      }
      if(!publishForm.value.miniPath){
        ElMessage.warning("请先输入路径")
        return
      }
      data.mount_type = 'mini_program'
      data.micro_app_info.micro_app_id = publishForm.value.miniId
      data.micro_app_info.micro_app_title = publishForm.value.miniTitle
      data.micro_app_info.micro_app_url = publishForm.value.miniPath
    }
  }else {
    url = 'api/scan_publish/xhs/save'
  }

  try {
    const response = await axiosUtil.post(url, data)
    if(response.data.code === 1) {
      ElMessage.success(response.data.msg)
      const qr_code = response.data.data.qr_code
      if(publishForm.value.publishType === 'douyin'){
        // 将地址转换为二维码图片
        douyinQrCode.value = await generateQRCode(qr_code)
      }else {
        // 将地址转换为二维码图片
        redBookAndroidQrCode.value = await generateQRCode(qr_code.android)
        redBookIOSQrCode.value = await generateQRCode(qr_code.ios)
      }
      showQrCodeDialog.value = true
      showPublishDialog.value = false
    }else {
      ElMessage.error(response.data.msg)
    }
  } catch (error) {
    ElMessage.error('发布失败，请重试')
  }
}

const handlePublishCancel = () => {
  showPublishDialog.value = false
  // 重置表单
  publishForm.value = {
    publishType: 'douyin',
    activityName: '',
    title: '',
    topic: [], // Reset to empty array for InputTag
    mount: 'none',
    dataAcquisition: true,
    scanCodeLimit: 0,
    picnums: 0,
    // POI相关字段
    poi1: '',
    poi2: '',
    poiSelect: '',
    // 小程序相关字段
    miniId: '',
    miniTitle: '',
    miniPath: ''
  }
}

const handleQrCodeConfirm = () =>{
  // 清空发布相关变量
  publishForm.value = {
    publishType: 'douyin',
    activityName: '',
    title: '',
    topic: [], // Reset to empty array for InputTag
    mount: 'none',
    dataAcquisition: true,
    scanCodeLimit: 0,
    picnums: 0,
    // POI相关字段
    poi1: '',
    poi2: '',
    poiSelect: '',
    // 小程序相关字段
    miniId: '',
    miniTitle: '',
    miniPath: ''
  }
  douyinQrCode.value = ""
  redBookAndroidQrCode.value = ""
  redBookIOSQrCode.value = ""
  showQrCodeDialog.value = false;

  // 清空城市数据
  cityData.value = [];
}

const handleChooseCityKeyWord = async () => {
  if(!publishForm.value.poi1){
    ElMessage.warning("请输入关键词")
    return
  }
  if(!publishForm.value.poi2){
    ElMessage.warning("请输入城市")
    return
  }
  try {
    const res = await axiosUtil.post('api/scan_publish/douyin/search_poi', {
      "keyword": publishForm.value.poi1,
      "city": publishForm.value.poi2
    })
    if(res.data.code){
      cityData.value = []
      res.data.code.forEach(item=>{
        const son = {
          value: item.poi_id,
          label: item.province  + item.city + item.district + item.address,
        }
        cityData.value.push(son)
      })
    }
  } catch (error) {
    ElMessage.error('搜索POI失败，请重试')
  }
}

// 发布视频事件
const handlePublicVideo = () => {
  console.log('点击授权发布按钮')
  showPublishDialog.value = true
}

const handlePackagedChange = (val: boolean) => {
  if (val) {
    // 获取当前激活的banner
    const currentBanner = digitalHumanList.value[currentIndex.value];
    if (!currentBanner || !currentBanner.packing_id) {
      ElMessage.warning('请先为当前数字人选择包装模版');
      formData.value.isPackaged = false;
    }
            } else {
        // 先停止所有正在播放的音频
        audioInstances.value.forEach((instance, index) => {
          if (instance && audioPlayingStates.value[index]) {
            instance.pause();
          }
        });

        // 取消包装时清空相关变量
        pictureContents.value = [];
        streamContent.value = [];
        audioUrls.value = [];
        audioPlayingStates.value = [];
        audioInstances.value = [];
        taskName.value = '';
      }
};

function onDriveTypeChange(type: 'text' | 'audio') {
  // 先停止所有正在播放的音频
  audioInstances.value.forEach((instance, index) => {
    if (instance && audioPlayingStates.value[index]) {
      instance.pause();
    }
  });

  driveType.value = type;
  if (type === 'text') {
    // 切换到文本驱动时清空相关变量
    formData.value.textContent = '';
    pictureContents.value = [];
    audioList.value = [];
    streamContent.value = [];
    audioUrls.value = [];
    audioPlayingStates.value = [];
    audioInstances.value = [];
    generateCount.value = 0;
    taskName.value = '';
  } else if (type === 'audio') {
    // 切换到音频驱动时清空相关变量
    formData.value.textContent = '';
    pictureContents.value = [];
    streamContent.value = [];
    audioUrls.value = [];
    audioPlayingStates.value = [];
    audioInstances.value = [];
    generateCount.value = 0;
    taskName.value = '';
  }
}
</script>

<style scoped>
.container {
  width: 100%;
  height: 100%;
  padding: 20px;
}

.el-row {
  height: 100%;
  margin: 0 !important;
}

.el-col {
  height: 100%;
}

.area-container {
  height: 100%;
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.3)"');
  backdrop-filter: blur(10px);
  border-radius: 12px;
  border: 1px solid v-bind('theme === "light" ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.4)"');
  box-shadow: 0 4px 6px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.3)"');
  transition: all 0.3s ease;
  padding: 15px;
}

.area-container:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.15)" : "rgba(0, 0, 0, 0.4)"');
  box-shadow: 0 6px 12px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.15)" : "rgba(0, 0, 0, 0.4)"');
  border-color: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.5)"');
}

.left-area {
  overflow-y: auto;
}

.left-area::-webkit-scrollbar {
  width: 6px;
}

.left-area::-webkit-scrollbar-thumb {
  background: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.3)" : "rgba(255, 255, 255, 0.3)"');
  border-radius: 3px;
}

.left-area::-webkit-scrollbar-track {
  background: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(255, 255, 255, 0.1)"');
}

.right-area {
  display: flex;
  flex-direction: column;
}

.content-nav {
  height: 60px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  background: transparent;
  border: none;
  box-shadow: none;
  margin-bottom: 20px;
}

.area-container:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.15)" : "rgba(0, 0, 0, 0.4)"');
  box-shadow: 0 6px 12px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.15)" : "rgba(0, 0, 0, 0.4)"');
  border-color: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.5)"');
}

.menu-container {
  overflow-y: auto;
}

.menu-title {
  color: #fff;
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 0%;
  min-width: 0;
}

.sub-menu-title {
  color: #fff;
  font-size: 16px;
  font-weight: 500;
  padding: 10px 0;
  margin-bottom: 10px;
  text-align: left;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.center-area, .right-area {
  min-height: 70vh;
}

.menu-container::-webkit-scrollbar {
  width: 6px;
}

.menu-container::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 3px;
}

.menu-container::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
}

.menu-item {
  margin-bottom: 15px;
}

.parent-menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 15px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  font-weight: 500;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.parent-menu:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}

.expand-icon {
  transition: transform 0.3s ease;
  color: #fff;
}

.expand-icon.is-expanded {
  transform: rotate(180deg);
}

.child-menu {
  margin-top: 8px;
  padding: 5px;
  animation: slideDown 0.3s ease;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.child-item {
  padding: 10px 15px;
  margin: 8px 0;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  font-size: 0.95em;
  text-align: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.child-item:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
  border-color: rgba(255, 255, 255, 0.4);
}

.child-item:active {
  transform: translateY(0);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.child-item.selected {
  background: rgba(64, 158, 255, 0.3);
  border-color: rgba(64, 158, 255, 0.5);
  color: #fff;
  box-shadow: 0 4px 8px rgba(64, 158, 255, 0.2);
}

.spacer {
  height: 5vh;
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 0 20px;
  margin-top: 3vh;
}

.nav-right {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: 16px;
}

.nav-btn {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  padding: 8px 20px;
  border-radius: 0;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 90px;
  white-space: nowrap;
}

.nav-btn:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.4)"');
  border-color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.3)" : "rgba(255, 255, 255, 0.3)"');
  box-shadow: 0 0 10px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
}

.btn-icon {
  font-size: 16px;
}

.title-section {
  margin-bottom: 20px;
}

.section-title {
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  font-size: 18px;
  font-weight: 500;
  margin: 0;
  padding-bottom: 10px;
  border-bottom: 1px solid v-bind('theme === "light" ? "rgba(0, 0, 0, 0.3)" : "rgba(255, 255, 255, 0.3)"');
}

.digital-human-section {
  padding: 10px 0;
}

.select-btn {
  width: 100%;
  margin-bottom: 15px;
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.2)" : "rgba(0, 0, 0, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
}

.select-btn:hover {
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(0, 0, 0, 0.4)"');
}

.digital-human-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.list-item {
  margin-bottom: 10px;
  padding: 8px;
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.2)"');
  border-radius: 6px;
  transition: all 0.3s ease;
}

.list-item:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.3)"');
}

.item-content {
  display: flex;
  align-items: center;
  gap: 10px;
}

.item-image {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
}

.item-name {
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  font-size: 14px;
}

:deep(.el-checkbox__label) {
  color: #fff;
}

:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #409EFF;
  border-color: #409EFF;
}

.drive-section {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.button-group {
  display: flex;
  gap: 0;
  background: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(255, 255, 255, 0.1)"');
  padding: 4px;
  border-radius: 6px;
  box-shadow: inset 0 2px 4px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.2)"');
  margin-bottom: 15px;
  flex-shrink: 0;
}

.button-group .el-button {
  border-radius: 0;
  margin: 0;
  flex: 1;
  height: 40px;
  font-weight: 500;
  transition: all 0.3s ease;
  border: none;
  background: transparent;
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "rgba(255, 255, 255, 0.8)"');
}

.button-group .el-button:first-child {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

.button-group .el-button:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

.button-group .el-button:hover {
  background: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(255, 255, 255, 0.1)"');
  color: v-bind('theme === "light" ? "#000" : "#fff"');
}

.button-group .el-button.el-button--primary {
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.2)" : "rgba(0, 0, 0, 0.3)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  box-shadow: 0 2px 8px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(0, 0, 0, 0.3)"');
}

.button-group .el-button.el-button--primary:hover {
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(0, 0, 0, 0.4)"');
}

.button-group .el-button.el-button--default {
  background: transparent;
  color: rgba(255, 255, 255, 0.8);
}

.button-group .el-button.el-button--default:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.text-area-container {
  margin-top: 15px;
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.2)"');
  border-radius: 8px;
  padding: 2px;
  box-shadow: inset 0 2px 4px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.2)"');
}

.text-area :deep(.el-textarea__inner) {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.3)" : "rgba(255, 255, 255, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  backdrop-filter: blur(5px);
  transition: all 0.3s ease;
  font-size: 14px;
  line-height: 1.5;
  resize: none;
}

.text-area :deep(.el-textarea__inner:focus) {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.15)" : "rgba(255, 255, 255, 0.4)"');
  border-color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.4)" : "rgba(255, 255, 255, 0.4)"');
  box-shadow: 0 0 0 2px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.1)" : "rgba(255, 255, 255, 0.1)"');
}

.text-area :deep(.el-textarea__inner::placeholder) {
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.6)" : "rgba(255, 255, 255, 0.6)"');
}

.audio-section {
  margin-top: 15px;
}

.upload-btn {
  width: 100%;
  margin-bottom: 15px;
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.2)" : "rgba(0, 0, 0, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.upload-btn:hover {
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(0, 0, 0, 0.4)"');
}

.audio-list {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.2)"');
  border-radius: 8px;
  padding: 10px;
}

.audio-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.3)"');
  border-radius: 6px;
  margin-bottom: 8px;
}

.audio-item:last-child {
  margin-bottom: 0;
}

.audio-info {
  display: flex;
  align-items: center;
  gap: 8px;
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
}

.audio-name {
  font-size: 14px;
}

.audio-actions {
  display: flex;
  gap: 8px;
}

.action-icon {
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  transition: all 0.3s ease;
}

.action-icon:hover {
  color: #ff4d4f;
}

.switch-section {
  display: none;
}

.custom-switch {
  --el-switch-on-color: #409EFF;
  --el-switch-off-color: rgba(255, 255, 255, 0.2);
}

.generate-section {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.generate-btn {
  width: 120px;
  height: 40px;
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.2)" : "rgba(0, 0, 0, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  font-size: 16px;
  transition: all 0.3s ease;
}

.generate-btn:hover {
  background: v-bind('theme === "light" ? "rgba(64, 158, 255, 0.3)" : "rgba(0, 0, 0, 0.4)"');
  transform: translateY(-2px);
  box-shadow: 0 4px 12px v-bind('theme === "light" ? "rgba(64, 158, 255, 0.2)" : "rgba(0, 0, 0, 0.3)"');
}

.generate-btn:active {
  transform: translateY(0);
}

.reset-btn {
  width: 120px;
  height: 40px;
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  font-size: 16px;
  transition: all 0.3s ease;
}

.reset-btn:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.4)"');
  transform: translateY(-2px);
  box-shadow: 0 4px 12px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(0, 0, 0, 0.3)"');
}

.reset-btn:active {
  transform: translateY(0);
}

.title-row {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 10px 0;
  margin-bottom: 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  width: 100%;
  box-sizing: border-box;
}
.menu-title {
  color: #fff;
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 0%;
  min-width: 0;
}
.nav-right {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: 16px;
}
.nav-btn {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.3)"');
  border: 1px solid v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.8)" : "#fff"');
  padding: 8px 20px;
  border-radius: 0;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 90px;
  white-space: nowrap;
}
.nav-btn:hover {
  background: v-bind('theme === "light" ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.4)"');
  border-color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.3)" : "rgba(255, 255, 255, 0.3)"');
  box-shadow: 0 0 10px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"');
}
.btn-icon {
  font-size: 16px;
}
.disclaimer-text {
  color: v-bind('theme === "light" ? "rgba(0, 0, 0, 0.6)" : "rgba(255, 255, 255, 0.6)"');
  font-size: 13px;
  line-height: 1.5;
  text-shadow: 0 1px 2px v-bind('theme === "light" ? "rgba(0, 0, 0, 0.2)" : "rgba(0, 0, 0, 0.4)"');
  flex: 1;
  margin-right: 20px;
}

.banner-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}
.banner-btn {
  background: rgba(0,0,0,0.1);
  border: none;
  font-size: 28px;
  width: 40px;
  height: 80px;
  cursor: pointer;
  color: #409EFF;
  border-radius: 8px;
  transition: background 0.2s;
}
.banner-btn:hover {
  background: #409EFF;
  color: #fff;
}
.banner-list {
  display: flex;
  align-items: center;
  gap: 20px;
  width: 420px; /* 3*140px */
  will-change: transform;
}
.banner-item {
  position: relative;
  width: 140px;
  height: 200px;
  margin: 0 auto;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  background: #fff;
  opacity: 0.6;
  transform: scale(0.85);
  transition: all 0.3s;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.banner-item.active {
  opacity: 1;
  transform: scale(1.1);
  box-shadow: 0 4px 16px #409EFF33;
}
.banner-item img {
  width: 100%;
  height: 80%;
  object-fit: cover;
}
.banner-name {
  text-align: center;
  font-size: 16px;
  color: #333;
  margin-top: 6px;
}
.banner-slide-enter-active, .banner-slide-leave-active {
  transition: all 0.4s cubic-bezier(.55,0,.1,1);
}
.banner-slide-enter-from {
  opacity: 0;
  transform: translateX(60px) scale(0.85);
}
.banner-slide-leave-to {
  opacity: 0;
  transform: translateX(-60px) scale(0.85);
}
.pro-tag {
  position: absolute;
  top: 8px;
  left: 8px;
  background: #ff9800;
  color: #fff;
  font-size: 12px;
  font-weight: bold;
  padding: 2px 8px;
  border-radius: 8px;
  z-index: 2;
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
.switch-row {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}
.switch-label {
  font-size: 15px;
  color: v-bind('theme === "light" ? "#333" : "#fff"') !important;
  font-weight: 400;
}
.generate-count-row {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 12px;
  background: linear-gradient(90deg, #eaf4ff 0%, #f7fbff 100%);
  box-shadow: 0 2px 8px rgba(64,158,255,0.08);
  border: 1px solid #e0eaff;
}
.generate-count-label {
  font-size: 15px;
  color: v-bind('theme === "light" ? "#333" : "#fff"') !important;
  font-weight: 400;
}
.generate-count-row, .switch-row {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 16px;
  background: v-bind('theme === "light" ? "rgba(64,158,255,0.06)" : "rgba(0,0,0,0.18)"');
  border-radius: 8px;
  padding: 10px 18px 10px 14px;
  box-shadow: 0 2px 8px v-bind('theme === "light" ? "rgba(64,158,255,0.08)" : "rgba(0,0,0,0.18)"');
  width: fit-content;
  min-width: 220px;
}
.generate-count-label, .switch-label {
  font-size: 15px;
  color: #222;
  font-weight: 500;
  letter-spacing: 1px;
  min-width: 70px;
}
.el-input-number, .custom-switch {
  border-radius: 6px !important;
  box-shadow: 0 1px 4px v-bind('theme === "light" ? "rgba(64,158,255,0.10)" : "rgba(0,0,0,0.22)"');
  background: v-bind('theme === "light" ? "#fff" : "#222"');
  transition: box-shadow 0.2s;
}
.el-input-number:hover, .custom-switch:hover {
  box-shadow: 0 2px 8px v-bind('theme === "light" ? "rgba(64,158,255,0.18)" : "rgba(0,0,0,0.28)"');
}
.beauty-counter {
  --el-input-number-width: 140px;
  --el-input-border-radius: 10px;
  --el-input-bg-color: #f4f8ff;
  --el-input-border-color: #a0cfff;
  --el-input-hover-border-color: #409eff;
  --el-input-focus-border-color: #409eff;
  --el-input-box-shadow: 0 2px 8px rgba(64,158,255,0.10);
  --el-input-font-size: 18px;
  --el-input-number-handler-bg-color: #e6f0ff;
  --el-input-number-handler-hover-bg-color: #409eff;
  --el-input-number-handler-color: #409eff;
  --el-input-number-handler-hover-color: #fff;
  width: var(--el-input-number-width);
  border-radius: var(--el-input-border-radius);
  background: var(--el-input-bg-color);
  box-shadow: var(--el-input-box-shadow);
  font-size: var(--el-input-font-size);
  border: 1.5px solid var(--el-input-border-color);
  transition: border 0.2s, box-shadow 0.2s;
}
.beauty-counter:hover,
.beauty-counter:focus-within {
  border-color: var(--el-input-hover-border-color);
  box-shadow: 0 4px 16px rgba(64,158,255,0.18);
}
.beauty-counter :deep(.el-input__inner) {
  background: transparent;
  border: none;
  font-size: 18px;
  color: #222;
  text-align: center;
}
.beauty-counter :deep(.el-input-number__increase),
.beauty-counter :deep(.el-input-number__decrease) {
  background: var(--el-input-number-handler-bg-color);
  color: var(--el-input-number-handler-color);
  border-radius: 6px;
  transition: background 0.2s, color 0.2s;
}
.beauty-counter :deep(.el-input-number__increase:hover),
.beauty-counter :deep(.el-input-number__decrease:hover) {
  background: var(--el-input-number-handler-hover-bg-color);
  color: var(--el-input-number-handler-hover-color);
}
/* 美化右侧多行文本输入框父容器的滚动条样式 */
.right-area > div[style*='overflow-y: auto']::-webkit-scrollbar {
  width: 8px;
  background: transparent;
}
.right-area > div[style*='overflow-y: auto']::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,0.18);
  border-radius: 6px;
  transition: background 0.2s;
}
.right-area > div[style*='overflow-y: auto']::-webkit-scrollbar-thumb:hover {
  background: rgba(64,158,255,0.35);
}
.right-area > div[style*='overflow-y: auto']::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 6px;
}
/* 右侧底部操作栏固定样式 */
.fixed-bottom-bar {
  position: absolute;
  right: 24px;
  bottom: 24px;
  display: flex;
  align-items: center;
  z-index: 10;
  background: rgba(64,158,255,0.12);
  border-radius: 8px;
  padding: 10px 24px;
  box-shadow: 0 2px 12px rgba(64,158,255,0.08);
}
.fixed-bottom-bar .el-button {
  margin-left: 10px;
}

/* 任务名称弹出框样式 */
:deep(.el-dialog) {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}

:deep(.el-dialog__header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px 24px;
  margin: 0;
}

:deep(.el-dialog__title) {
  color: white;
  font-size: 18px;
  font-weight: 600;
}

:deep(.el-dialog__body) {
  padding: 24px;
}

:deep(.el-dialog__footer) {
  padding: 16px 24px;
  border-top: 1px solid #f0f0f0;
  background: #fafafa;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

:deep(.el-dialog .el-input__inner) {
  border-radius: 8px;
  border: 2px solid #e4e7ed;
  transition: all 0.3s ease;
  font-size: 16px;
  padding: 12px 16px;
}

:deep(.el-dialog .el-input__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

:deep(.el-dialog .el-button) {
  border-radius: 8px;
  padding: 10px 20px;
  font-weight: 500;
  transition: all 0.3s ease;
}

:deep(.el-dialog .el-button--primary) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

:deep(.el-dialog .el-button--primary:hover) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.wechat-list-main {
  overflow-y: auto;
}

.wechat-list-main::-webkit-scrollbar {
  width: 6px;
}

.wechat-list-main::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 3px;
}

.wechat-list-main::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.5);
}

.wechat-list-main::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
}

.generate-video-bottom {
  width: 100%;
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}
.switch-row, .generate-count-row {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-switch) {
  background: transparent !important;
  box-shadow: none !important;
}
:deep(.el-switch__core) {
  background: transparent !important;
  box-shadow: none !important;
}
.audio-list-area {
  margin-top: 24px;
}
.audio-list-item {
  display: flex;
  align-items: center;
  background: #e6f7ff;
  border-radius: 8px;
  margin-bottom: 12px;
  padding: 8px;
}
.audio-cover {
  width: 48px;
  height: 48px;
  border-radius: 6px;
  object-fit: cover;
  margin-right: 12px;
}
.audio-info-block {
  flex: 1;
}
.audio-name {
  font-size: 15px;
  color: #333;
}
.audio-player {
  width: 100%;
  margin-top: 4px;
}

/* 发布设置弹窗样式 */
.publish-form {
  padding: 20px;
}

.form-section {
  margin-bottom: 24px;
}

.section-label {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  margin-bottom: 8px;
}

.publish-type-buttons {
  display: flex;
  gap: 12px;
}

.type-btn {
  flex: 1;
  padding: 10px 16px;
  border: 1px solid #dcdfe6;
  background: #fff;
  color: #606266;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  font-size: 14px;
}

.type-btn:hover {
  border-color: #409eff;
  color: #409eff;
}

.type-btn.active {
  background: #409eff;
  border-color: #409eff;
  color: #fff;
}

.form-input {
  width: 100%;
}

.form-tip {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.mount-buttons {
  display: flex;
  gap: 12px;
}

.mount-btn {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #dcdfe6;
  background: #fff;
  color: #606266;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  font-size: 12px;
}

.mount-btn:hover {
  border-color: #409eff;
  color: #409eff;
}

.mount-btn.active {
  background: #409eff;
  border-color: #409eff;
  color: #fff;
}

.data-acquisition-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.scan-limit-input {
  width: 120px;
}

/* 二维码显示样式 */
.qr-code-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 10px;
}

.qr-code-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.qr-code-title {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  text-align: center;
}

.qr-code-image {
  width: 150px;
  height: 150px;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  padding: 8px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
</style>

